package com.ctbri.concurrency.ex30;

import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

class Sender implements Runnable {
	private Random rand = new Random(47);
	private BlockingQueue<Character> charQueue;
	public Sender(BlockingQueue<Character> charQueue) {
		this.charQueue = charQueue;
	}
	public void run() {
		try{
			while(!Thread.interrupted())
				for(char c ='A'; c <= 'z'; c++){
					charQueue.put(c);
					TimeUnit.MILLISECONDS.sleep(rand.nextInt(500));
				}
		} catch(InterruptedException e) {
			System.out.println(e + " Sender sleep interrupted");
		}
	}
}
class Reciever implements Runnable {
	private BlockingQueue<Character> charQueue;
	public Reciever(BlockingQueue<Character> charQueue) {
		this.charQueue = charQueue;
	}
	@Override
	public void run() {
		try{
			while(!Thread.interrupted()) {
				System.out.print("Read: " + charQueue.take() + ", ");
			}
		} catch(InterruptedException e) {
			System.out.println(e + " Reciever read exception");
		}
	}
}
public class PipedIO {
	public static void main(String[] args) throws Exception {
		BlockingQueue<Character> queue = new LinkedBlockingQueue<>();
		Sender sender = new Sender(queue);
		Reciever reciever = new Reciever(queue);
		ExecutorService exec = Executors.newCachedThreadPool();
		exec.execute(sender);
		exec.execute(reciever);
		TimeUnit.SECONDS.sleep(4);
		exec.shutdownNow();
	}
}
